#include <stdio.h>
#include <stdlib.h>
#include <pic18f6722.h>

#define uint unsigned int
#define uchar unsigned char



#define STOP    0
#define FORWARD 1
#define BACK    2

void Device_MotorInitialize();
void Device_MotorSleep(uchar nSLEEP);
void Device_MotorReset(uchar nReset);
void Device_MotorDecayMode(uchar DecayMode);
uchar Device_MotorCheckFault();
void Device_MotorOutControl(uint);
void Device_MotorSetCurrent(int percentage);

#define MOTOR_DECAY    RE4  
#define MOTOR_FAULT    RB0
#define MOTOR_nSLEEP   RE3
#define MOTOR_nRESET   RE2

#define MOTOR_I0       RE7
#define MOTOR_I1       RD0
#define MOTOR_I2       RD1
#define MOTOR_I3       RD2
#define MOTOR_I4       RD3

#define MOTOR_IN1      RE6
#define MOTOR_IN2      RE5

#define ENCODE_HALL_A  RA2
#define ENCODE_HALL_A  RA1

#define ENABLE         1
#define DISENABLE      0

//*********************************************************************
/* Initialize the DRV8842
 * input void 
 * return: void
 * author: Guichuan.He
 * date: 2016-9-23
*/
//**********************************************************************
void Device_MotorInitialize()
{
   Device_MotorReset(DISENABLE); 
   Device_MotorSleep(DISENABLE);  
   Device_MotorDecayMode(0);
   Device_MotorSetCurrent(0x05);
   Device_MotorOutControl(STOP);  
}

//*********************************************************************
/* Logic high to enable device,logic low to enter low-power sleep mode. Internal pulldown.
 * input nSLEEP = 1, Enable DRV8842
 * input nSLEEP = 0, Disenable DRV8842     
 * return: void
 * author: Guichuan.He
 * date: 2016-9-23
*/
//**********************************************************************
void Device_MotorSleep(uchar nSLEEP)
{
    if(nSLEEP == 0)
        MOTOR_nSLEEP = ENABLE;
    else
        MOTOR_nSLEEP = DISENABLE;
}
//*********************************************************************
/*Active-low reset input initializes the logic and disables the H-bridge outputs. Internal pulldown.
 * input nReset = 1, Enable DRV8842
 * input nReset = 0, Reset DRV8842     
 * return: void
 * author: Guichuan.He
 * date: 2016-9-23
*/
//**********************************************************************
void Device_MotorReset(uchar nReset)
{
    if( nReset == 0 )
        MOTOR_nRESET = ENABLE; 
    else
        MOTOR_nRESET = DISENABLE; 
}
//*********************************************************************
/*LOW  = slow decay, open = mixed dacay
 *high = fast decay, Internal pulldown and pullup.
 * input DecayMode = 1, fast decay
 * input DecayMode =0, slow decay    
 * return: void
 * author: Guichuan.He
 * date: 2016-9-23
*/
//**********************************************************************
void Device_MotorDecayMode(uchar DecayMode)
{
    if( DecayMode == 1)
        MOTOR_DECAY = 1;
    else
        MOTOR_DECAY = 0;
}
//*********************************************************************
/*Logic low when in fault condition ( over temperature, over current)
 * input void
 * return: 0 - fault
 *         1 - normal
 * author: Guichuan.He
 * date: 2016-9-23
*/
//**********************************************************************
uchar Device_MotorCheckFault()
{
    if( MOTOR_FAULT == 1 )
        return 1;
    else
        return 0;
}
//********************************************************************
/*Sets winding current as a percentage of full-scale. Internal pulldown.
 * input:  percentage 0x00-0%, 0x1F-100%
 * return: void
 * author: Guichuan.He
 * date: 2016-9-23
*/
//**********************************************************************
void Device_MotorSetCurrent(int percentage)
{
   MOTOR_I0 = ((percentage & 0x01) == 0x01)? 1:0;
   MOTOR_I1 = ((percentage & 0x02) == 0x02)? 1:0;
   MOTOR_I2 = ((percentage & 0x04) == 0x04)? 1:0;
   MOTOR_I3 = ((percentage & 0x08) == 0x08)? 1:0;
   MOTOR_I4 = ((percentage & 0x10) == 0x10)? 1:0;
}
//********************************************************************
/*Logic input controls state of OUT1 & OUT2. Internal pulldown.Either input can also be used for PWM control the load.
 *    xIN1  |  xIN2  |  xOUT1  |  xOUT2       
 *     0        0         L         L
 *     0        1         L         H
 *     1        0         H         L
 *     1        1         H         H
 * return: void
 * author: Guichuan.He
 * date: 2016-9-23
*/
//**********************************************************************
void Device_MotorOutControl(uint Director)
{
    switch(Director)
    {
        case STOP:
            MOTOR_IN1 = 0;
            MOTOR_IN2 = 0;
            break;
        case FORWARD:
            MOTOR_IN1 = 0;
            MOTOR_IN2 = 1;
            break;
        case BACK:
            MOTOR_IN1 = 1;
            MOTOR_IN2 = 0;
            break;
        default:
            MOTOR_IN1 = 0;
            MOTOR_IN2 = 0;
            break;
            break;
    }

}
